package com.plian.system.service.wf;


import com.plian.Tools.TokenUtil;
import com.plian.system.bean.wf.UserPOJO;
import com.plian.system.bean.wf.UserTaskPOJO;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.helper.wf.SimulationHelper;
import com.plian.system.helper.wf.WorkFlowHelper;
import com.plian.system.helper.wf.WorkflowProcessListHelper;
import com.plian.system.model.ObjResult;


import org.flowable.common.engine.impl.util.CollectionUtil;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.runtime.ProcessInstance;


import org.flowable.task.api.Task;
import org.flowable.ui.modeler.domain.ApprovalPoints;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;


/**
 * @Author：zsk
 * @Package：com.plian.system.service.wf
 * @Project：xt-gzw-20250227
 * @name：WorkflowProcessListHelperTwo
 * @Date：2025/3/7 15:59
 * @Filename：WorkflowProcessListHelperTwo
 */

public class WorkflowProcessListHelperTwo {
    private static final int UNKNOWN_INDEX = -1;
    private int currentIndex = -1;
    private int nextIndex = 0;
    private int preIndex = -1;
    private UserTaskPOJO currentNode = null;
    private UserTaskPOJO nextNode = null;
    private UserTaskPOJO preNode = null;
    private List<UserTaskPOJO> userPOJOList = null;
    private UserTaskPOJO turnBackNode = null;
    @Resource
    private WorkFlowHelper workFlowHelper;
    private String processInstanceId;
    private RuntimeService runtimeService;

    @Autowired
    public void setRuntimeService(RuntimeService runtimeService) {
        this.runtimeService = runtimeService;
    }

    public WorkflowProcessListHelperTwo(List<UserTaskPOJO> userPOJOList, WorkFlowHelper workFlowHelper, String processInstanceId) {
        this.processInstanceId = processInstanceId;
        this.workFlowHelper = workFlowHelper;
        this.updateInstance(userPOJOList);
    }
    public WorkflowProcessListHelperTwo(){

    }
    private void updateInstance(List<UserTaskPOJO> userPOJOList) {
        if (userPOJOList != null && userPOJOList.size() > 0) {
            this.userPOJOList = userPOJOList;
            int size = userPOJOList.size();

            for(int i = size - 1; i >= 0; --i) {
                UserTaskPOJO node = (UserTaskPOJO)userPOJOList.get(i);
                if (node.getTaskState() == 2 || node.getTaskState() == 6 || node.getTaskState() == 4 || node.getTaskState() == 3 || node.getTaskState() == 9) {
                    this.currentIndex = i;
                    this.currentNode = node;
                    this.nextIndex = i + 1;
                    this.preIndex = i - 1;
                    if (this.nextIndex < size) {
                        this.nextNode = (UserTaskPOJO)userPOJOList.get(this.nextIndex);
                    } else {
                        this.nextIndex = -1;
                        this.nextNode = null;
                    }

                    if (this.preIndex >= 0) {
                        this.preNode = (UserTaskPOJO)userPOJOList.get(this.preIndex);
                    } else {
                        this.preIndex = -1;
                        this.preNode = null;
                    }
                    break;
                }

                if (i == 0 && node.getTaskState() == 5) {
                    this.nextIndex = 0;
                    this.nextNode = node;
                }
            }

        }
    }

    public boolean canApproval(String userId) {
        if (this.nextIndex != -1) {
            this.nextNode = (UserTaskPOJO)this.userPOJOList.get(this.nextIndex);
            List<UserPOJO> userList = this.nextNode.getUserList();
            boolean b = false;
            if (CollectionUtil.isNotEmpty(userList)) {
                b = userList.stream().anyMatch((user) -> {
                    return user.getId().equals(userId);
                });
            }

            if (!b) {
                b = true;
            }

            return b;
        } else {
            return false;
        }
    }

    public boolean canSubmit(String userId) {
        return true;
    }

    public boolean canTurnBack(String userId) {
        boolean isAssigneeUser = this.canApproval(userId);
        boolean isFirst = false;
        if (this.nextNode != null) {
            isFirst = this.nextNode.getTaskDefineId().equals(((UserTaskPOJO)this.userPOJOList.get(0)).getTaskDefineId());
        }

        return !isFirst && isAssigneeUser;
    }

    public boolean canBackToStash(String id) {
        return this.currentNode != null && this.currentNode.getUserList().stream().anyMatch((user) -> {
            return user.getId().equals(id);
        }) && this.currentIndex == this.userPOJOList.size() - 1;
    }

    public int getRollBackState(String userId) {
        if (this.nextNode != null && "前加签".equals(this.nextNode.getRemark()) && ((UserTaskPOJO)this.userPOJOList.get(this.nextIndex + 1)).getUserList().stream().anyMatch((user) -> {
            return user.getId().equals(userId);
        })) {
            return 2;
        } else {
            return this.nextNode != null && !"前加签".equals(this.nextNode.getRemark()) && this.currentNode != null && !"前加签".equals(this.currentNode.getRemark()) && this.currentNode.getUserList().stream().anyMatch((user) -> {
                return user.getId().equals(userId);
            }) && this.currentNode.getTaskState() != 3 && this.currentNode.getTaskState() != 4 && this.currentNode.getTaskState() != 9 ? 1 : 0;
        }
    }

    public boolean isRollBackBeforeSign() {
        return "前加签".equals(this.nextNode.getRemark());
    }

    public List<UserTaskPOJO> beforeSignReject(String comment, UserPOJO userPOJO) {
        List<UserTaskPOJO> userTaskPOJOS = new LinkedList(this.userPOJOList);
        UserTaskPOJO next = (UserTaskPOJO)userTaskPOJOS.get(this.nextIndex);
        if (!this.canApproval(userPOJO.getId())) {
            throw new MyRuntimeException(new ObjResult("您不是审批人"));
        } else {
            next.setTaskState(4);
            next.setComment(comment);
            next.setUserList(new ArrayList(1));
            next.setUserPOJO(userPOJO);
            next.setFinishTime(new Date());
            if (CollectionUtil.isNotEmpty(next.getApprovalPointsList())) {
                Iterator var5 = next.getApprovalPointsList().iterator();

                while(var5.hasNext()) {
                    ApprovalPoints points = (ApprovalPoints)var5.next();
                    points.setChecked(1);
                }
            }

            if (this.nextIndex + 1 < userTaskPOJOS.size()) {
                ((UserTaskPOJO)userTaskPOJOS.get(this.nextIndex + 1)).setTaskState(1);
            }

            return userTaskPOJOS;
        }
    }

    public List<UserTaskPOJO> agreeOrSubmit(String comment, UserPOJO userPOJO) {
        List<UserTaskPOJO> userTaskPOJOS = new LinkedList(this.userPOJOList);
        UserTaskPOJO firstPojo = (UserTaskPOJO)userTaskPOJOS.get(0);
        UserTaskPOJO next = (UserTaskPOJO)userTaskPOJOS.get(this.nextIndex);
        if (next.getTaskDefineId().equals(firstPojo.getTaskDefineId())) {
            if (!this.canSubmit(userPOJO.getId())) {
                throw new MyRuntimeException(new ObjResult("申请失败"));
            }

            next.setTaskState(6);
        } else {
            if (!this.canApproval(userPOJO.getId())) {
                throw new MyRuntimeException(new ObjResult("您不是审批人"));
            }

            next.setTaskState(2);
        }

        next.setComment(comment);
        next.setUserList(new ArrayList(1));
        next.setUserPOJO(userPOJO);
        next.setFinishTime(new Date());
        if (this.nextIndex + 1 < userTaskPOJOS.size()) {
            ((UserTaskPOJO)userTaskPOJOS.get(this.nextIndex + 1)).setTaskState(1);
        }

        return userTaskPOJOS;
    }

    public List<UserTaskPOJO> updateProcess(LinkedList<UserTaskPOJO> newList) {
        String taskDefineId = ((UserTaskPOJO)this.userPOJOList.get(this.nextIndex)).getTaskDefineId();
        int index = 0;

        for(int i = 0; i < newList.size(); ++i) {
            if (((UserTaskPOJO)newList.get(i)).getTaskDefineId().equals(taskDefineId)) {
                index = i;
            }
        }

        List<UserTaskPOJO> dealedNewList = newList.subList(index, newList.size());
        List<UserTaskPOJO> dealedOldList = this.userPOJOList.subList(0, index);
        dealedOldList.addAll(dealedNewList);
        return dealedOldList;
    }

    public List<UserTaskPOJO> rollBack(UserPOJO userPOJO) {
        if (this.getRollBackState(userPOJO.getId()) != 1) {
            throw new MyRuntimeException(new ObjResult("不可撤回"));
        } else {
            List<UserTaskPOJO> userTaskPOJOS = new LinkedList(this.userPOJOList);
            UserTaskPOJO current = (UserTaskPOJO)userTaskPOJOS.get(this.currentIndex);
            UserTaskPOJO firstPojo = (UserTaskPOJO)userTaskPOJOS.get(0);
            if (firstPojo.getTaskDefineId().equals(current.getTaskDefineId())) {
                current.setTaskState(5);
            } else {
                current.setTaskState(1);
            }

            current.setFinishTime(new Date());
            ((UserTaskPOJO)userTaskPOJOS.get(this.nextIndex)).setTaskState(0);
            return userTaskPOJOS;
        }
    }

    public List<UserTaskPOJO> turnBack(String comment, List<ApprovalPoints> approvalPointsList, UserPOJO userPOJO, SimulationHelper simulationHelper, ProcessInstance processInstance, Task task) throws Exception {
        if (!this.canTurnBack(userPOJO.getId())) {
            throw new MyRuntimeException(new ObjResult("退回上一步失败"));
        } else if (((UserTaskPOJO)this.userPOJOList.get(1)).getTaskDefineId().equals(task.getTaskDefinitionKey())) {
            this.turnBackNode = (UserTaskPOJO)this.userPOJOList.get(0);
            return this.returnFirst(approvalPointsList, comment, userPOJO);
        } else {
            UserTaskPOJO next = (UserTaskPOJO)this.userPOJOList.get(this.nextIndex);
            next.setTaskState(4);
            next.setUserList(new ArrayList(1));
            next.setUserPOJO(userPOJO);
            next.setApprovalPointsList(approvalPointsList);
            next.setComment(comment);
            next.setFinishTime(new Date());
            this.updateInstance(this.userPOJOList);
            List<UserTaskPOJO> newList = simulationHelper.simulation(processInstance, processInstance.getProcessVariables(), false);
            ((UserTaskPOJO)newList.get(0)).setUserList(new ArrayList());
            ((UserTaskPOJO)newList.get(0)).setUserPOJO((UserPOJO)((UserTaskPOJO)this.userPOJOList.get(0)).getUserList().get(0));
            List<UserTaskPOJO> oldSubList = this.userPOJOList.subList(0, this.currentIndex + 1);
            int connectIndex = -1;

            for(int j = this.currentIndex; j >= 0 && connectIndex == -1; --j) {
                UserTaskPOJO oldPojo = (UserTaskPOJO)this.userPOJOList.get(j);

                for(int i = 0; i < newList.size(); ++i) {
                    if (((UserTaskPOJO)newList.get(i)).getTaskDefineId().equals(oldPojo.getTaskDefineId())) {
                        connectIndex = i;
                        break;
                    }
                }
            }

            if (connectIndex == -1) {
                oldSubList = newList;
                this.turnBackNode = (UserTaskPOJO)newList.get(0);
            } else {
                List<UserTaskPOJO> newSubList = newList.subList(connectIndex - 1, newList.size());
                ((UserTaskPOJO)newList.get(0)).setTaskState(1);
                ((List)oldSubList).addAll(newSubList);
                this.turnBackNode = (UserTaskPOJO)newList.get(connectIndex - 1);
            }

            return (List)oldSubList;
        }
    }

    public List<UserTaskPOJO> returnFirst(List<ApprovalPoints> approvalPointsList, String comment, UserPOJO userPOJO) {
        if (!this.canApproval(userPOJO.getId())) {
            throw new MyRuntimeException(new ObjResult("您不是办理人"));
        } else {
            List<UserTaskPOJO> userTaskPOJOS = new LinkedList(this.userPOJOList);
            UserTaskPOJO next = (UserTaskPOJO)userTaskPOJOS.get(this.nextIndex);
            next.setComment(comment);
            next.setTaskState(3);
            next.setUserList(new ArrayList(1));
            next.setUserPOJO(userPOJO);
            next.setFinishTime(new Date());
            return userTaskPOJOS;
        }
    }

    public List<UserTaskPOJO> agree(String comment, UserPOJO userPOJO) {
        List<UserTaskPOJO> userTaskPOJOS = new LinkedList(this.userPOJOList);
        UserTaskPOJO firstPojo = (UserTaskPOJO)userTaskPOJOS.get(0);
        UserTaskPOJO next = (UserTaskPOJO)userTaskPOJOS.get(this.nextIndex);
        if (next.getTaskDefineId().equals(firstPojo.getTaskDefineId())) {
            if (!this.canSubmit(userPOJO.getId())) {
                throw new MyRuntimeException("申请失败");
            }

            next.setTaskState(6);
        } else {
            if (!this.canOneClickApproval(userPOJO.getId())) {
                throw new MyRuntimeException("您不是审批人");
            }

            next.setTaskState(2);
        }

        next.setComment(comment);
        next.setUserList(new ArrayList(1));
        next.setUserPOJO(userPOJO);
        next.setFinishTime(new Date());
        Iterator var6 = next.getApprovalPointsList().iterator();

        while(var6.hasNext()) {
            ApprovalPoints points = (ApprovalPoints)var6.next();
            points.setChecked(1);
        }

        if (this.nextIndex + 1 < userTaskPOJOS.size()) {
            ((UserTaskPOJO)userTaskPOJOS.get(this.nextIndex + 1)).setTaskState(1);
        }

        return userTaskPOJOS;
    }

    public boolean canOneClickApproval(String userId) {
        if (this.nextIndex != -1) {
            this.nextNode = (UserTaskPOJO)this.userPOJOList.get(this.nextIndex);
            List<UserPOJO> userList = this.nextNode.getUserList();
            boolean b = false;
            if (CollectionUtil.isNotEmpty(userList)) {
                b = userList.stream().anyMatch((user) -> {
                    return user.getId().equals(userId);
                });
            }

            if (!b) {
                b = true;
            }

            return b;
        } else {
            return false;
        }
    }

    public List<UserTaskPOJO> submitAfterReturnFirst(SimulationHelperTwo simulationHelperTwo, ProcessInstance processInstance, String comment, UserPOJO userPOJO) {
        if (this.currentNode != null && this.currentNode.getTaskState() == 9) {
            UserTaskPOJO next = (UserTaskPOJO)this.userPOJOList.get(this.nextIndex);
            next.setFinishTime(new Date());
            next.setTaskState(6);
            return this.userPOJOList;
        } else {
            List<UserTaskPOJO> newList = simulationHelperTwo.simulation(processInstance, processInstance.getProcessVariables(), false);
            WorkflowProcessListHelperTwo helper = new WorkflowProcessListHelperTwo(newList, this.workFlowHelper, this.processInstanceId);
            newList = helper.agreeOrSubmit(comment, userPOJO);
            int refuseIndex = -1;

            for(int i = this.userPOJOList.size() - 1; i >= 0; --i) {
                if (((UserTaskPOJO)this.userPOJOList.get(i)).getTaskState() == 3) {
                    refuseIndex = i;
                    break;
                }

                if (((UserTaskPOJO)this.userPOJOList.get(i)).getTaskState() == 5 && i == 0) {
                    return newList;
                }
            }

            if (refuseIndex == -1) {
                throw new MyRuntimeException(new ObjResult("提交失败！"));
            } else {
                List<UserTaskPOJO> oldSubList = this.userPOJOList.subList(0, refuseIndex + 1);
                oldSubList.addAll(newList);
                return oldSubList;
            }
        }
    }

    public List<UserTaskPOJO> beforeAddSign(SimulationHelper simulationHelper, UserPOJO loginUserPOJO, UserPOJO signUserPOJO) {
        List<UserTaskPOJO> userTaskPOJOS = new LinkedList(this.userPOJOList);
        UserTaskPOJO next = (UserTaskPOJO)userTaskPOJOS.get(this.nextIndex);
        next.setTaskState(0);
        next.setUserList(new ArrayList(1));
        next.setUserPOJO(loginUserPOJO);
        UserTaskPOJO beforeSignNode = new UserTaskPOJO();
        beforeSignNode.setTaskState(1);
        beforeSignNode.setUserList(new ArrayList(1));
        beforeSignNode.setUserPOJO(signUserPOJO);
        beforeSignNode.setTaskName("加签");
        beforeSignNode.setTaskDefineId(next.getTaskDefineId());
        beforeSignNode.setRemark("前加签");
        beforeSignNode.setBelongedOrganizationId(TokenUtil.getTokenOrgId());
        userTaskPOJOS.add(this.nextIndex, beforeSignNode);
        return userTaskPOJOS;
    }

    public List<UserTaskPOJO> rollBackBeforeSign(SimulationHelper simulationHelper, ProcessInstance processInstance) throws Exception {
        LinkedList<UserTaskPOJO> newList = simulationHelper.simulation(processInstance, processInstance.getProcessVariables(), false);
        List<UserTaskPOJO> oldList = this.userPOJOList.subList(0, this.currentIndex + 1);
        List<UserTaskPOJO> subedNewList = newList.subList(this.nextIndex, newList.size());
        oldList.addAll(subedNewList);
        return oldList;
    }

    public int getCurrentIndex() {
        return this.currentIndex;
    }

    public int getNextIndex() {
        return this.nextIndex;
    }

    public int getPreIndex() {
        return this.preIndex;
    }

    public UserTaskPOJO getCurrentNode() {
        return this.currentNode;
    }

    public UserTaskPOJO getNextNode() {
        return this.nextNode;
    }

    public UserTaskPOJO getPreNode() {
        return this.preNode;
    }

    public UserTaskPOJO getTurnBackNode() {
        return this.turnBackNode;
    }
}
